Amazon Redshift: 【新機能】列圧縮の圧縮エンコードとして、ZSTDが追加されました
はじめに
好物はインフラとフロントエンドのかじわらゆたかです。
Redshiftの列の圧縮エンコードとしてZSTDが追加になりました。
ZSTDはFacebook が開発を行っている圧縮アルゴリズムのようです。 facebook/zstd: Zstandard - Fast real-time compression algorithm
一点勘違いしそうなのが、copyコマンドの取り込み形式の追加ではなく、列形式の圧縮アルゴリズムの追加となります。 そのためZSTD形式でのファイルを用意するとかそういうことは必要ではなく、テーブル作成時の圧縮エンコードでZSTDを指定することで適用することができます。
今回性能検証のため、AWS のドキュメントのテーブル設計のチューニングのチュートリアルに則ってパフォーマンス等を確認していきます。
チュートリアル: テーブル設計のチューニング - Amazon Redshift
今回の検証については、以下の構成で行っております。
- Node Type: dw2.large
- Nodes: 2
テストデータセットの作成
テーブル作成
チュートリアルではすべて圧縮無しで作成していますが、今回は圧縮なしとZSTDで比較をしたいので、ZSTDを圧縮エンコードとしたテーブルを作成します。 ZSTD版のクエリは以下になります。
CREATE TABLE part_ZSTD ( p_partkey INTEGER NOT NULL encode ZSTD, p_name VARCHAR(22) NOT NULL encode ZSTD, p_mfgr VARCHAR(6) NOT NULL encode ZSTD, p_category VARCHAR(7) NOT NULL encode ZSTD, p_brand1 VARCHAR(9) NOT NULL encode ZSTD, p_color VARCHAR(11) NOT NULL encode ZSTD, p_type VARCHAR(25) NOT NULL encode ZSTD, p_size INTEGER NOT NULL encode ZSTD, p_container VARCHAR(10) NOT NULL encode ZSTD ); CREATE TABLE supplier_ZSTD ( s_suppkey INTEGER NOT NULL encode ZSTD, s_name VARCHAR(25) NOT NULL encode ZSTD, s_address VARCHAR(25) NOT NULL encode ZSTD, s_city VARCHAR(10) NOT NULL encode ZSTD, s_nation VARCHAR(15) NOT NULL encode ZSTD, s_region VARCHAR(12) NOT NULL encode ZSTD, s_phone VARCHAR(15) NOT NULL encode ZSTD ); CREATE TABLE dwdate_ZSTD ( d_datekey INTEGER NOT NULL encode ZSTD, d_date VARCHAR(19) NOT NULL encode ZSTD, d_dayofweek VARCHAR(10) NOT NULL encode ZSTD, d_month VARCHAR(10) NOT NULL encode ZSTD, d_year INTEGER NOT NULL encode ZSTD, d_yearmonthnum INTEGER NOT NULL encode ZSTD, d_yearmonth VARCHAR(8) NOT NULL encode ZSTD, d_daynuminweek INTEGER NOT NULL encode ZSTD, d_daynuminmonth INTEGER NOT NULL encode ZSTD, d_daynuminyear INTEGER NOT NULL encode ZSTD, d_monthnuminyear INTEGER NOT NULL encode ZSTD, d_weeknuminyear INTEGER NOT NULL encode ZSTD, d_sellingseason VARCHAR(13) NOT NULL encode ZSTD, d_lastdayinweekfl VARCHAR(1) NOT NULL encode ZSTD, d_lastdayinmonthfl VARCHAR(1) NOT NULL encode ZSTD, d_holidayfl VARCHAR(1) NOT NULL encode ZSTD, d_weekdayfl VARCHAR(1) NOT NULL encode ZSTD ); CREATE TABLE lineorder_ZSTD ( lo_orderkey INTEGER NOT NULL encode ZSTD, lo_linenumber INTEGER NOT NULL encode ZSTD, lo_custkey INTEGER NOT NULL encode ZSTD, lo_partkey INTEGER NOT NULL encode ZSTD, lo_suppkey INTEGER NOT NULL encode ZSTD, lo_orderdate INTEGER NOT NULL encode ZSTD, lo_orderpriority VARCHAR(15) NOT NULL encode ZSTD, lo_shippriority VARCHAR(1) NOT NULL encode ZSTD, lo_quantity INTEGER NOT NULL encode ZSTD, lo_extendedprice INTEGER NOT NULL encode ZSTD, lo_ordertotalprice INTEGER NOT NULL encode ZSTD, lo_discount INTEGER NOT NULL encode ZSTD, lo_revenue INTEGER NOT NULL encode ZSTD, lo_supplycost INTEGER NOT NULL encode ZSTD, lo_tax INTEGER NOT NULL encode ZSTD, lo_commitdate INTEGER NOT NULL encode ZSTD, lo_shipmode VARCHAR(10) NOT NULL encode ZSTD );
データロード
チュートリアルでは、AccessKeyとSecretAccessKeyを用いた形になっていますが、IAM Roleからも当該リソースはアクセス可能なため、 IAM Roleで当該リソースへのアクセスを行なってCopyコマンドを実行しました。 lineorderは全件取り込むと無圧縮で50Gほどになるため、一部のみ取り込んでいます。
copy customer from 's3://awssampledbuswest2/ssbgz/customer' CREDENTIALS 'aws_iam_role=arn:aws:iam::nnnnnnnnnnnn:role/redshift-role-mmmmmmmmm' gzip compupdate off region 'us-west-2'; copy dwdate from 's3://awssampledbuswest2/ssbgz/dwdate' credentials 'aws_iam_role=arn:aws:iam::nnnnnnnnnnnn:role/redshift-role-mmmmmmmmm' gzip compupdate off region 'us-west-2'; copy lineorder from 's3://awssampledbuswest2/ssbgz/lineorder0000_part_00.gz' credentials 'aws_iam_role=arn:aws:iam::nnnnnnnnnnnn:role/redshift-role-mmmmmmmmm' gzip compupdate off region 'us-west-2'; copy part from 's3://awssampledbuswest2/ssbgz/part' credentials 'aws_iam_role=arn:aws:iam::nnnnnnnnnnnn:role/redshift-role-mmmmmmmmm' gzip compupdate off region 'us-west-2'; copy supplier from 's3://awssampledbuswest2/ssbgz/supplier' credentials 'aws_iam_role=arn:aws:iam::nnnnnnnnnnnn:role/redshift-role-mmmmmmmmm' gzip compupdate off region 'us-west-2';
Copyコマンド実行時間については以下のようになりました。
圧縮エンコード | 実行時間 |
---|---|
圧縮なし | 5 min 16 sec |
ZSTD | 5min 42sec |
Copyの時間は圧縮を実行したテーブルに対して5%ほどのCopy時間が増えています。 Copyについては圧縮の有無でのパフォーマンスの劣化等はそれほど気にしなくても良さそうです。
次にストレージの使用量を調べてみます。
table | mbytes |
---|---|
customer | 368 |
customer_zstd | 140 |
dwdate | 80 |
dwdate_zstd | 80 |
lineorder | 6404 |
lineorder_zstd | 3240 |
supplier | 124 |
supplier_zstd | 60 |
テーブルのストレージ単位はMbyteになっています。 dwdateテーブル以外は圧縮でテーブルの容量がかなり削減できていることがわかります。
クエリパフォーマンス(ソートキー・分散スタイル未設定)
上記の状態でのクエリのパフォーマンスを測定してみたいと思います。 測定方法はチュートリアルのステップ 2: システムパフォーマンスをテストしてベースラインを確定するを元におこないます。
まずは無圧縮のテーブルに対して、実行した結果は以下のようになりました。
query | milli second |
---|---|
Query1 | 606 |
Query2 | 3266 |
Query3 | 2974 |
次にZSTDで全カラムを圧縮したテーブルに対して行なってみました。
query | milli second |
---|---|
Query1 | 3023 |
Query2 | 4565 |
Query3 | 4813 |
特にQuery1の時間が無圧縮だったときに比べて5倍ほどの差がついています。 推測ではありますが、格納しているレコード数が多く、また全カラムを圧縮しているため、 解凍に時間がかかったため、このような結果になったのではと推測しております。
さすがにこれでは優位性がストレージ容量だけになってしまうので、もう少し突っ込んでみたいと思います。
クエリパフォーマンス(ソートキー・分散スタイル設定済み)
比較対象としては以下になります。
- ステップ 6: テストデータセットを再作成する の方針で作成したテーブル
- 上記の方針でソートキーと分散スタイルを設定し、それソートキー以外はZSTD形式にて圧縮した場合(ソートキーは無圧縮)
まずはCopyコマンドの実行結果から
圧縮エンコード | 実行時間 |
---|---|
チュートリアル | 8 min 34 sec |
ZSTD + Sort + 分散 | 6min 39sec |
チュートリアル版の方が処理時間がかかっていますが、これは初回Copy時に圧縮タイプを決めていたりするのが原因かなと思っています。
ストレージの使用量について調べてみます。
table | mbytes |
---|---|
customer_sort | 302 |
customer_zstd_sort | 274 |
dwdate_sort | 80 |
dwdate_zstd_sort | 80 |
lineorder_sort | 3501 |
lineorder_zstd_sort | 3393 |
part_sort | 112 |
part_zstd_sort | 116 |
supplier_sort | 118 |
supplier_zstd_sort | 108 |
*_sortとなっているテーブルがチュートリアルに基いて作成したテーブル、 *_zstd_sortとなっているのがソートキーと分散スタイルを設定し、それソートキー以外はZSTD形式にて圧縮したテーブルとなります。
ZSTDで圧縮かけたほうが最大で1割くらい自動で決められたエンコードよりデータ容量が少なくなっていることがわかります。
最後にクエリの性能を調べてみたいと思います。
チュートリアル版
query | milli second |
---|---|
Query1 | 258 |
Query2 | 3305 |
Query3 | 783 |
ZSTD + ソートキー + 分散スタイル
query | milli second |
---|---|
Query1 | 523 |
Query2 | 3991 |
Query3 | 951 |
実行するクエリによっては1~2割程度実行時間に差が出た形になりますが、一番差があるところがは2倍差がついていたりします。 実際に投入されたデータに基いて決められた圧縮エンコードが有利といえばそれまでですが、 何も考えずに設定したZSTDとの差があまり無いのというの点は評価できるのではと思います。 圧縮エンコーディングについては、見直すこと前提でひとまずZSTDとするといった使い方ができるのかなと思います。
結論
新しい圧縮エンコーディングであるZSTDについて調べてみました。
絶対にZSTDだよ!というほど優位性のある結果が得れなかったのは残念ですが、 一括で設定した場合においても性能がそんなにひどく劣化するといった事が無い事が確認できました。
実際にどういった用途に用いれるのかは今後検討していく必要があるのかなと言う感じです。